package com.woniu113.junk.user.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.io.FileTypeUtil;
import com.woniu113.junk.commons.util.RedisUtil;
import com.woniu113.junk.commons.util.TokenUtil;

import com.woniu113.junk.user.Param.userInfo.*;
import com.woniu113.junk.user.controller.form.userInfo.*;

import com.woniu113.junk.user.dto.SFRZDTO;
import com.woniu113.junk.user.dto.address.FindAddressDTO;
import com.woniu113.junk.user.dto.userinfo.FindUserInfoDTO;
import com.woniu113.junk.user.model.AddressInfo;
import com.woniu113.junk.user.model.UserInfo;
import com.woniu113.junk.user.service.UserInfoService;
import com.woniu113.junk.commons.model.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import jdk.nashorn.internal.runtime.FindProperty;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author 蜡笔没了小新
 * @since 2024年10月16日
 */
@RestController
@RequestMapping("/userInfo")
@Api("用户信息")
public class UserInfoController {
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private UserInfoService userInfoService;

    /**
     *用户注册板块
     */
    @GetMapping("/sendRegisterCode")
    @ApiOperation("发送注册验证码")
    public Result sendRegisterCode(@RequestParam String phoneNumber) throws Exception {
      System.out.println(phoneNumber);
      userInfoService.sendRegisterCode(phoneNumber);
      return Result.getResult().setMsg("发送成功").setCode(200);
    }
    @PostMapping("/addUserInfo")
    @ApiOperation("注册用户信息")
    public Result addUserInfo(@RequestBody AddUserInfoForm form) throws Exception {
      System.out.println("用户名" + form.getUserName());
      System.out.println("密码" + form.getPassword());
      System.out.println("电话" + form.getPhoneNumber());
      System.out.println("验证码" + form.getCode());
      System.out.println("昵称" + form.getNikeName());
      AddUserInfoParam param = BeanUtil.toBean(form, AddUserInfoParam.class);
      userInfoService.addUserInfo(param);
      return Result.getResult().setMsg("添加用户信息成功").setCode(200);
    }

    /**
     *用户登录板块
     */
    @PostMapping("/userLog")
    @ApiOperation("用户密码登录")
    public Result<UserInfo> userLog(@RequestBody UserLogForm form, HttpServletResponse response) throws Exception {
      UserInfo userInfo =userInfoService.adminLog(BeanUtil.toBean(form, UserLogParam.class));
      //签发jwt(令牌)(会话跟踪)
      HashMap<String, Object> map = new HashMap<>();//键值对(存入用户信息)
      map.put("userId",userInfo.getUserId());
      String accessToken = TokenUtil.createToken(map, 60);//传入键值对和有效期(1分钟)
      String refreshToken = TokenUtil.createToken(map, 24 * 60);//长token,保存在redis中(有效期为1天)
      System.out.println("accessToken1"+accessToken);
      System.out.println("refreshToken1"+refreshToken);
      //以短token为键,以长token为值,将长token存到redis中,同时设置过期时间保持与长token一致(设置的是以秒为单位的)
      redisUtil.set(accessToken,refreshToken,24*60*60);
      System.out.println("redisUtil.get(accessToken):"+redisUtil.get(accessToken));
      //设置响应头,通过响应头将jwt响应给客户端(前端)
      response.setHeader("token", accessToken);//响应头的名字,令牌(通过双token机制响应给用户的为短token)
      //在跨域请求访问时 必须公开该请求头 前端才能获取到
      response.setHeader("Access-Control-Expose-Headers","token");
      return Result.getResult(UserInfo.class).setData(userInfo);
    }
    @GetMapping("/sendLoginCode")
    @ApiOperation("发送登录验证码")
    public Result sendLoginCode(@RequestParam String phoneNumber) throws Exception {
      userInfoService.sendLoginCode(phoneNumber);
      return Result.getResult().setMsg("发送成功").setCode(200);
    }
    @PostMapping("/userCodeLogin")
    @ApiOperation("用户手机号登录")
    public Result<UserInfo> userCodeLogin(@RequestBody UserCodeLoginForm form, HttpServletResponse response) throws Exception {
      UserInfo userInfo =userInfoService.userCodeLogin(BeanUtil.toBean(form, UserCodeLoginParam.class));
      //签发jwt(令牌)(会话跟踪)
      HashMap<String, Object> map = new HashMap<>();//键值对(存入用户信息)
      map.put("userId",userInfo.getUserId());
      String accessToken = TokenUtil.createToken(map, 60);//传入键值对和有效期(1分钟)
      String refreshToken = TokenUtil.createToken(map, 24 * 60);//长token,保存在redis中(有效期为1天)
      System.out.println("accessToken1"+accessToken);
      System.out.println("refreshToken1"+refreshToken);
      //以短token为键,以长token为值,将长token存到redis中,同时设置过期时间保持与长token一致(设置的是以秒为单位的)
      redisUtil.set(accessToken,refreshToken,24*60*60);
      System.out.println("redisUtil.get(accessToken):"+redisUtil.get(accessToken));
      //设置响应头,通过响应头将jwt响应给客户端(前端)
      response.setHeader("token", accessToken);//响应头的名字,令牌(通过双token机制响应给用户的为短token)
      //在跨域请求访问时 必须公开该请求头 前端才能获取到
      response.setHeader("Access-Control-Expose-Headers","token");
      return Result.getResult(UserInfo.class).setData(userInfo);
    }

    /**
     *用户账号板块
     */
    @GetMapping("/disableAccount")
    @ApiOperation("禁用账号")
    public Result disableAccount(@RequestParam Integer userId) {
        System.out.println("禁用账号id" + userId);
        userInfoService.disableAccount(userId);
        return Result.getResult().setMsg("禁用账号成功");
    }
    @GetMapping("/deleteAccount")
    @ApiOperation("删除账号")
    public Result deleteAccount(@RequestParam Integer userId){
      userInfoService.deleteAccount(userId);
      return Result.getResult().setMsg("删除账号成功");
    }
    @GetMapping("/enableAccount")
    @ApiOperation("启用账号")
    public Result enableAccount(@RequestParam Integer userId) {
        System.out.println("启用账号id" + userId);
        userInfoService.enableAccount(userId);
        return Result.getResult().setMsg("启用账号成功");
    }

    /**
     *用户个人中心板块
     */
    @GetMapping("/userCheckOldPassword")
    @ApiOperation("用户校验旧密码")
    public Result userCheckOldPassword(@RequestParam String Password,@RequestHeader String token) throws Exception {
      int userId = Integer.parseInt(TokenUtil.parseToken(redisUtil.get(token)).get("userId").toString());
      UserPasswordParam param = new UserPasswordParam();
      param.setUserId(userId);
      param.setPassword(Password);
      userInfoService.userCheckOldPassword(param);
      return Result.getResult().setMsg("校验旧密码成功");
    }
    @GetMapping("/userUpdatePassword")
    @ApiOperation("用户修改密码")
    public Result userUpdatePassword(@RequestParam String Password,@RequestHeader String token) throws Exception {
        int userId = Integer.parseInt(TokenUtil.parseToken(redisUtil.get(token)).get("userId").toString());
        UserPasswordParam param = new UserPasswordParam();
        param.setUserId(userId);
        param.setPassword(Password);
        userInfoService.userUpdatePassword(param);
        return Result.getResult().setMsg("修改密码成功");
    }
    @PostMapping("/updateUserHeaderImg")
    @ApiOperation("修改用户头像")
    public Result updateUserHeaderImg(MultipartFile userHeaderImg, @RequestHeader String token) throws Exception {
        System.out.println(userHeaderImg);
        int userId = Integer.parseInt(TokenUtil.parseToken(redisUtil.get(token)).get("userId").toString());
        //通过文件头信息判断文件类型
        String type = FileTypeUtil.getType(userHeaderImg.getInputStream());//得到传入文件的文件类型(需要得到传入的image的输入流)
        System.out.println("图片类型：" + type);
        if (!(type.equals("jpg") || type.equals("png"))) {//不是这两种类型,表示传入的文件不合法
            throw new Exception("图片类型错误");
        }
        UserHeaderImgParam param = new UserHeaderImgParam();
        param.setUserId(userId);
        param.setUserHeaderImg(userHeaderImg);
        userInfoService.updateUserHeaderImg(param);
        return Result.getResult().setMsg("修改用户头像成功");
    }
    @GetMapping("/update")
    @ApiOperation("修改昵称信息")
    public Result update(@RequestParam("nickName") String nikeName,@RequestHeader String token) throws Exception {
        System.out.println("新昵称" + nikeName);
        int userId = Integer.parseInt(TokenUtil.parseToken(redisUtil.get(token)).get("userId").toString());
        UserNikeNameParam param = new UserNikeNameParam();
        param.setUserId(userId);
        param.setUserNikeName(nikeName);
        userInfoService.updateUser(param);
        return Result.getResult().setMsg("修改用户信息成功");
    }
    @GetMapping("/sendUpCode")
    @ApiOperation("发送修改手机号验证码")
    public Result sendUpCode(@RequestParam String phoneNumber) throws Exception {
        System.out.println(phoneNumber);
        userInfoService.sendUpCode(phoneNumber);
        return Result.getResult().setMsg("发送成功").setCode(200);
    }
    @PostMapping("/upUserPhone")
    @ApiOperation("修改用户手机号")
    public Result upUserPhone(@RequestBody UserUpPhoneForm form,@RequestHeader String token) throws Exception {
        System.out.println(form.getUserPhone());
        System.out.println(form.getCode());
        int userId = Integer.parseInt(TokenUtil.parseToken(redisUtil.get(token)).get("userId").toString());
        UserUpPhoneParam param = BeanUtil.toBean(form, UserUpPhoneParam.class);
        param.setUserId(userId);
        userInfoService.upUserPhone(param);
        return Result.getResult().setMsg("修改用户手机号成功");
    }

    /**
     * 用户积分和信誉分操作板块
     */
    @GetMapping("/selectIntegral")
    @ApiOperation("根据用户id查询用户积分")
      public Result<UserInfo> selectIntegral(@RequestParam Integer userId){
      UserInfo userInfo = userInfoService.getById(userId);
      return Result.getResult(UserInfo.class).setData(userInfo);
    }
    @PostMapping("/addIntegralById")
    @ApiOperation("根据用户id增加积分")
    public Result addIntegralById(@RequestBody IntegralForm form){
      IntegralParam param = BeanUtil.toBean(form, IntegralParam.class);
      userInfoService.addIntegralById(param);
      return Result.getResult().setMsg("增加积分成功");
    }
    @PostMapping("/reduceIntegralById")
    @ApiOperation("根据用户id减少积分")
    public Result reduceIntegralById(@RequestBody IntegralForm form){
      IntegralParam param = BeanUtil.toBean(form, IntegralParam.class);
      userInfoService.reduceIntegralById(param);
      return Result.getResult().setMsg("减少积分成功");
    }
    @PostMapping("/addScore")
    @ApiOperation("根据用户id增加信誉分")
    public Result addScore(@RequestBody ScoreForm form){
      ScoreParam param = BeanUtil.toBean(form, ScoreParam.class);
      userInfoService.addScore(param);
      return Result.getResult().setMsg("增加信誉分成功");
    }
    @PostMapping("/reduceScore")
    @ApiOperation("根据用户id减少信誉分")
    public Result reduceScore(@RequestBody ScoreForm form){
      ScoreParam param = BeanUtil.toBean(form, ScoreParam.class);
      userInfoService.reduceScore(param);
      return Result.getResult().setMsg("减少信誉分成功");
    }

    /**
     * 用户信息查询板块
     */
//    @PostMapping("/findAll")
//    @ApiOperation("查询所有用户信息")
//    public Result<Page<UserInfo>> findAll(@RequestBody UserFdAllForm form) {
//        System.out.println("昵称"+form.getNikeName());
//        System.out.println("状态"+form.getUserStatus());
//        System.out.println("积分上限"+form.getMaxIntegral());
//        System.out.println("积分下限"+form.getMinIntegral());
//        System.out.println("分页"+form.getPageNum());
//        System.out.println("分页"+form.getPageSize());
//        Page<UserInfo> userInfoPage = userInfoService.findAll(BeanUtil.toBean(form, UserFdAllParam.class));
//        return Result.getPageResult(UserInfo.class).setData(userInfoPage).setMsg("查询所有用户信息成功").setCode(200);
//    }

    @PostMapping("/findAll")
    @ApiOperation("查询所有用户信息")
    public Result<List<UserInfo>> findAll(@RequestBody UserFdAllForm form) {
        System.out.println("昵称"+form.getNikeName());
        System.out.println("状态"+form.getUserStatus());
        System.out.println("积分上限"+form.getMaxIntegral());
        System.out.println("积分下限"+form.getMinIntegral());
        System.out.println("分页"+form.getPageNum());
        System.out.println("分页"+form.getPageSize());
        // 计算查询的起始索引
        int offset = (form.getPageNum() - 1) * form.getPageSize();
        FindUserInfoDTO dto = userInfoService.findAll(BeanUtil.toBean(form, UserFdAllParam.class),offset);
        Integer total = dto.getTotal();
        return Result.getListResult(UserInfo.class).setData(dto.getList()).setMsg("查询所有用户信息成功").setCode(200).setTotal(total);
    }

    @GetMapping("/userInfo")
    @ApiOperation("查询用户自己信息")
    public Result<UserInfo> userInfo(@RequestHeader String token) throws Exception {
      int userId = Integer.parseInt(TokenUtil.parseToken(redisUtil.get(token)).get("userId").toString());
      UserInfo userInfo = userInfoService.userInfo(userId);
      return Result.getResult(UserInfo.class).setData(userInfo);
    }

    /**
     * 实名认证
     */
    @PostMapping("/realNameAuthentication")
    @ApiOperation("实名认证")
    public Result<SFRZDTO> realNameAuthentication(@RequestBody RealNameAuthenticationForm form, @RequestHeader String token) throws Exception {
      int userId = Integer.parseInt(TokenUtil.parseToken(redisUtil.get(token)).get("userId").toString());
      RealNameAuthenticationParam param = BeanUtil.toBean(form, RealNameAuthenticationParam.class);
      param.setUserId(userId);
      SFRZDTO sfrzdto = userInfoService.realNameAuthentication(param);
      return Result.getResult(SFRZDTO.class).setData(sfrzdto).setMsg("实名认证成功");
    }

    @GetMapping("/selectUserById")
    @ApiOperation("通过id查询用户信息(无条件)")
    public Result<UserInfo> selectUserById(@RequestParam("userId") Integer userId){
        UserInfo userInfo = userInfoService.getById(userId);
        return Result.getResult(UserInfo.class).setData(userInfo).setMsg("通过id查询用户信息");
    }



    @GetMapping("/test")
    public Result<Integer> test(@RequestParam Integer ss){
      return Result.getResult(Integer.class).setData(ss);
    }
}

